home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Games Collection 1 / software vault.zip / software vault / CDR10 / TGE129C.ZIP / SOURCE / 800X600.ASM < prev    next >
Assembly Source File  |  1993-08-20  |  44KB  |  2,248 lines

  1. ; 800x600x256 (requires register-compatible VGA+)
  2. ; Loadable driver for The Graphics Engine
  3. ; Copyright (c) 1993 by Matthew Hildebrand
  4. ; Turbo Assembler syntax
  5. ; Portions by John Bridges
  6.  
  7. IDEAL
  8. P486N            ; 386 code, but we want 486 alignment
  9. MODEL LARGE
  10.  
  11.  
  12. SCREEN_WIDE    =    800
  13. SCREEN_DEEP    =    600
  14. NUM_COLOURS    =    256
  15.  
  16.  
  17.         CODESEG
  18.         ORG    0
  19.  
  20. ;*** Signature
  21.             db    'TGE3'
  22. ;*** Non-I/O functions
  23. _initGraphics        dw    initGraphics        ; initGraphics
  24.             dw    ?
  25. _deInitGraphics        dw    0            ; deInitGraphics
  26.             dw    ?
  27. _setPaletteReg        dw    setPaletteReg        ; setPaletteReg
  28.             dw    ?
  29. _getPaletteReg        dw    getPaletteReg        ; getPaletteReg
  30.             dw    ?
  31. _setBlockPalette    dw    setBlockPalette        ; setBlockPalette
  32.             dw    ?
  33. _getBlockPalette    dw    getBlockPalette        ; getBlockPalette
  34.             dw    ?
  35. _colourCloseTo        dw    0            ; colourCloseTo
  36.             dw    ?
  37. _colourCloseToX        dw    0            ; colourCloseToX
  38.             dw    ?
  39. _imageSize        dw    0            ; imageSize
  40.             dw    ?
  41. _imageSizeDim        dw    0            ; imageSizeDim
  42.             dw    ?
  43. _setPage        dw    0            ; setPage (not implemented yet)
  44.             dw    ?
  45.  
  46. ;*** Currently active I/O functions (filled in by loadGraphDriver())
  47.             dd    20    DUP(?)
  48.  
  49. ;*** Input functions
  50. _getImage_scr        dw    0            ; getImage
  51.             dw    ?
  52. _getImage_mem        dw    0
  53.             dw    ?
  54. _getLine_scr        dw      getLine_scr              ; getLine
  55.             dw    ?
  56. _getLine_mem        dw    getLine_mem
  57.             dw    ?
  58. _getPixel_scr        dw    getPixel_scr        ; getPixel
  59.             dw    ?
  60. _getPixel_mem        dw    getPixel_mem
  61.             dw    ?
  62.  
  63. ;*** Output functions
  64. _putImage_scr_copy    dw    0            ; putImage
  65.             dw    ?
  66. _putImage_scr_and    dw    0
  67.             dw    ?
  68. _putImage_scr_not    dw    0
  69.             dw    ?
  70. _putImage_scr_or    dw    0
  71.             dw    ?
  72. _putImage_scr_xor    dw    0
  73.             dw    ?
  74. _putImage_mem_copy    dw    0
  75.             dw    ?
  76. _putImage_mem_and    dw    0
  77.             dw    ?
  78. _putImage_mem_not    dw    0
  79.             dw    ?
  80. _putImage_mem_or    dw    0
  81.             dw    ?
  82. _putImage_mem_xor    dw    0
  83.             dw    ?
  84. _putImageInv_scr_copy    dw    0            ; putImageInv
  85.             dw    ?
  86. _putImageInv_scr_and    dw    0
  87.             dw    ?
  88. _putImageInv_scr_not    dw      0
  89.             dw    ?
  90. _putImageInv_scr_or    dw      0
  91.             dw    ?
  92. _putImageInv_scr_xor    dw    0
  93.             dw    ?
  94. _putImageInv_mem_copy    dw    0
  95.             dw    ?
  96. _putImageInv_mem_and    dw    0
  97.             dw    ?
  98. _putImageInv_mem_not    dw    0
  99.             dw    ?
  100. _putImageInv_mem_or    dw    0
  101.             dw    ?
  102. _putImageInv_mem_xor    dw    0
  103.             dw    ?
  104. _putLine_scr_copy          dw    putLine_scr_copy    ; putLine
  105.             dw    ?
  106. _putLine_scr_and          dw      0
  107.             dw    ?
  108. _putLine_scr_not          dw      0
  109.             dw    ?
  110. _putLine_scr_or          dw      0
  111.             dw    ?
  112. _putLine_scr_xor          dw    0
  113.             dw    ?
  114. _putLine_mem_copy    dw      putLine_mem_copy
  115.             dw    ?
  116. _putLine_mem_and    dw      0
  117.             dw    ?
  118. _putLine_mem_not    dw      0
  119.             dw    ?
  120. _putLine_mem_or        dw      0
  121.             dw    ?
  122. _putLine_mem_xor    dw    0
  123.             dw    ?
  124. _putLineInv_scr_copy       dw    0            ; putLineInv
  125.             dw    ?
  126. _putLineInv_scr_and       dw    0
  127.             dw    ?
  128. _putLineInv_scr_not       dw    0
  129.             dw    ?
  130. _putLineInv_scr_or       dw    0
  131.             dw    ?
  132. _putLineInv_scr_xor       dw    0
  133.             dw    ?
  134. _putLineInv_mem_copy    dw    0
  135.             dw    ?
  136. _putLineInv_mem_and    dw    0
  137.             dw    ?
  138. _putLineInv_mem_not    dw    0
  139.             dw    ?
  140. _putLineInv_mem_or    dw    0
  141.             dw    ?
  142. _putLineInv_mem_xor    dw    0
  143.             dw    ?
  144. _putPixel_scr_copy    dw    putPixel_scr_copy    ; putPixel
  145.             dw    ?
  146. _putPixel_scr_and    dw      0
  147.             dw    ?
  148. _putPixel_scr_not    dw      0
  149.             dw    ?
  150. _putPixel_scr_or    dw      0
  151.             dw    ?
  152. _putPixel_scr_xor    dw    0
  153.             dw    ?
  154. _putPixel_mem_copy    dw    putPixel_mem_copy
  155.             dw    ?
  156. _putPixel_mem_and    dw      putPixel_mem_and
  157.             dw    ?
  158. _putPixel_mem_not    dw      putPixel_mem_not
  159.             dw    ?
  160. _putPixel_mem_or    dw      putPixel_mem_or
  161.             dw    ?
  162. _putPixel_mem_xor    dw    putPixel_mem_xor
  163.             dw    ?
  164. _line_scr_copy        dw    0            ; line
  165.             dw    ?
  166. _line_scr_and        dw      0
  167.             dw    ?
  168. _line_scr_not        dw      0
  169.             dw    ?
  170. _line_scr_or        dw      0
  171.             dw    ?
  172. _line_scr_xor        dw    0
  173.             dw    ?
  174. _line_mem_copy        dw    0
  175.             dw    ?
  176. _line_mem_and        dw    0
  177.             dw    ?
  178. _line_mem_not        dw    0
  179.             dw    ?
  180. _line_mem_or        dw    0
  181.             dw    ?
  182. _line_mem_xor        dw    0
  183.             dw    ?
  184. _horizLine_scr_copy    dw    horizLine_scr_copy      ; horizLine
  185.             dw    ?
  186. _horizLine_scr_and    dw      0
  187.             dw    ?
  188. _horizLine_scr_not    dw      0
  189.             dw    ?
  190. _horizLine_scr_or    dw      0
  191.             dw    ?
  192. _horizLine_scr_xor    dw    0
  193.             dw    ?
  194. _horizLine_mem_copy    dw    horizLine_scr_copy
  195.             dw    ?
  196. _horizLine_mem_and    dw      0
  197.             dw    ?
  198. _horizLine_mem_not    dw      0
  199.             dw    ?
  200. _horizLine_mem_or    dw      0
  201.             dw    ?
  202. _horizLine_mem_xor    dw    0
  203.             dw    ?
  204. _vertLine_scr_copy    dw    0             ; vertLine
  205.             dw    ?
  206. _vertLine_scr_and    dw    0
  207.             dw    ?
  208. _vertLine_scr_not    dw    0
  209.             dw    ?
  210. _vertLine_scr_or    dw    0
  211.             dw    ?
  212. _vertLine_scr_xor    dw    0
  213.             dw    ?
  214. _vertLine_mem_copy    dw    0
  215.             dw    ?
  216. _vertLine_mem_and    dw    0
  217.             dw    ?
  218. _vertLine_mem_not    dw    0
  219.             dw    ?
  220. _vertLine_mem_or    dw    0
  221.             dw    ?
  222. _vertLine_mem_xor    dw    0
  223.             dw    ?
  224. _drawRect_scr_copy    dw    0            ; drawRect
  225.             dw    ?
  226. _drawRect_scr_and    dw    0
  227.             dw    ?
  228. _drawRect_scr_not    dw    0
  229.             dw    ?
  230. _drawRect_scr_or    dw    0
  231.             dw    ?
  232. _drawRect_scr_xor    dw    0
  233.             dw    ?
  234. _drawRect_mem_copy    dw    0
  235.             dw    ?
  236. _drawRect_mem_and    dw    0
  237.             dw    ?
  238. _drawRect_mem_not    dw    0
  239.             dw    ?
  240. _drawRect_mem_or    dw    0
  241.             dw    ?
  242. _drawRect_mem_xor    dw    0
  243.             dw    ?
  244. _filledRect_scr_copy    dw    0            ; filledRect
  245.             dw    ?
  246. _filledRect_scr_and    dw      0
  247.             dw    ?
  248. _filledRect_scr_not    dw      0
  249.             dw    ?
  250. _filledRect_scr_or    dw      0
  251.             dw    ?
  252. _filledRect_scr_xor    dw    0
  253.             dw    ?
  254. _filledRect_mem_copy    dw    0
  255.             dw    ?
  256. _filledRect_mem_and    dw    0
  257.             dw    ?
  258. _filledRect_mem_not    dw    0
  259.             dw    ?
  260. _filledRect_mem_or    dw    0
  261.             dw    ?
  262. _filledRect_mem_xor    dw    0
  263.             dw    ?
  264. _clearGraphics_scr_copy    dw    0            ; clearGraphics
  265.             dw    ?
  266. _clearGraphics_scr_and    dw      0
  267.             dw    ?
  268. _clearGraphics_scr_not    dw      0
  269.             dw    ?
  270. _clearGraphics_scr_or    dw      0
  271.             dw    ?
  272. _clearGraphics_scr_xor    dw    0
  273.             dw    ?
  274. _clearGraphics_mem_copy    dw    0
  275.             dw    ?
  276. _clearGraphics_mem_and    dw    0
  277.             dw    ?
  278. _clearGraphics_mem_not    dw    0
  279.             dw    ?
  280. _clearGraphics_mem_or    dw    0
  281.             dw    ?
  282. _clearGraphics_mem_xor    dw    0
  283.             dw    ?
  284. _ellipse_scr_copy    dw    0            ; ellipse
  285.             dw    ?
  286. _ellipse_scr_and    dw    0
  287.             dw    ?
  288. _ellipse_scr_not    dw    0
  289.             dw    ?
  290. _ellipse_scr_or        dw    0
  291.             dw    ?
  292. _ellipse_scr_xor    dw    0
  293.             dw    ?
  294. _ellipse_mem_copy    dw    0
  295.             dw    ?
  296. _ellipse_mem_and    dw    0
  297.             dw    ?
  298. _ellipse_mem_not    dw    0
  299.             dw    ?
  300. _ellipse_mem_or        dw    0
  301.             dw    ?
  302. _ellipse_mem_xor    dw    0
  303.             dw    ?
  304. _filledEllipse_scr_copy    dw    0            ; filledEllipse
  305.             dw    ?
  306. _filledEllipse_scr_and    dw    0
  307.             dw    ?
  308. _filledEllipse_scr_not    dw    0
  309.             dw    ?
  310. _filledEllipse_scr_or    dw    0
  311.             dw    ?
  312. _filledEllipse_scr_xor    dw    0
  313.             dw    ?
  314. _filledEllipse_mem_copy    dw    0
  315.             dw    ?
  316. _filledEllipse_mem_and    dw    0
  317.             dw    ?
  318. _filledEllipse_mem_not    dw    0
  319.             dw    ?
  320. _filledEllipse_mem_or    dw    0
  321.             dw    ?
  322. _filledEllipse_mem_xor    dw    0
  323.             dw    ?
  324. _circle_scr_copy    dw    0            ; circle
  325.             dw    ?
  326. _circle_scr_and        dw    0
  327.             dw    ?
  328. _circle_scr_not        dw    0
  329.             dw    ?
  330. _circle_scr_or        dw    0
  331.             dw    ?
  332. _circle_scr_xor        dw    0
  333.             dw    ?
  334. _circle_mem_copy    dw    0
  335.             dw    ?
  336. _circle_mem_and        dw    0
  337.             dw    ?
  338. _circle_mem_not        dw    0
  339.             dw    ?
  340. _circle_mem_or        dw    0
  341.             dw    ?
  342. _circle_mem_xor        dw    0
  343.             dw    ?
  344. _filledCircle_scr_copy    dw    0            ; filledCircle
  345.             dw    ?
  346. _filledCircle_scr_and    dw    0
  347.             dw    ?
  348. _filledCircle_scr_not    dw    0
  349.             dw    ?
  350. _filledCircle_scr_or    dw    0
  351.             dw    ?
  352. _filledCircle_scr_xor    dw    0
  353.             dw    ?
  354. _filledCircle_mem_copy    dw    0
  355.             dw    ?
  356. _filledCircle_mem_and    dw    0
  357.             dw    ?
  358. _filledCircle_mem_not    dw    0
  359.             dw    ?
  360. _filledCircle_mem_or    dw    0
  361.             dw    ?
  362. _filledCircle_mem_xor    dw    0
  363.             dw    ?
  364. _fillRegion_scr_copy    dw    0            ; fillRegion
  365.             dw    ?
  366. _fillRegion_scr_and    dw    0
  367.             dw    ?
  368. _fillRegion_scr_not    dw    0
  369.             dw    ?
  370. _fillRegion_scr_or    dw    0
  371.             dw    ?
  372. _fillRegion_scr_xor    dw    0
  373.             dw    ?
  374. _fillRegion_mem_copy    dw    0
  375.             dw    ?
  376. _fillRegion_mem_and    dw    0
  377.             dw    ?
  378. _fillRegion_mem_not    dw    0
  379.             dw    ?
  380. _fillRegion_mem_or    dw    0
  381.             dw    ?
  382. _fillRegion_mem_xor    dw    0
  383.             dw    ?
  384. _fillLine_scr_copy    dw    0            ; fillLine
  385.             dw    ?
  386. _fillLine_scr_and    dw      0
  387.             dw    ?
  388. _fillLine_scr_not    dw      0
  389.             dw    ?
  390. _fillLine_scr_or    dw      0
  391.             dw    ?
  392. _fillLine_scr_xor    dw    0
  393.             dw    ?
  394. _fillLine_mem_copy    dw    0
  395.             dw    ?
  396. _fillLine_mem_and    dw      0
  397.             dw    ?
  398. _fillLine_mem_not    dw      0
  399.             dw    ?
  400. _fillLine_mem_or    dw      0
  401.             dw    ?
  402. _fillLine_mem_xor    dw    0
  403.             dw    ?
  404. ;*** Mode information
  405. scrnMaxX        dw    799    ; physical dimensions
  406. scrnMaxY        dw    599
  407. maxColour        dw    255    ; maximum colour number
  408. xRatio                   dw    4    ; aspect ratio 4:3 (800:600 in
  409. yRatio            dw    3    ;   lowest terms)
  410. bitsPerPixel        dw    8    ; 8 bits per pixel
  411. inMaxX            dw    799    ; current input screen dimensions
  412. inMaxY            dw    599
  413. outMaxX            dw    799    ; current output screen dimensions
  414. outMaxY            dw    599
  415. inScreenWide        dw    ?    ; needed only for virtual screens
  416. outScreenWide        dw    ?
  417. ;*** Viewport information
  418. inViewportULX        dw    0
  419. inViewportULY        dw    0
  420. inViewportLRX        dw    799
  421. inViewportLRY        dw    599
  422. outViewportULX        dw    0
  423. outViewportULY        dw    0
  424. outViewportLRX        dw    799
  425. outViewportLRY        dw    599
  426. ;*** Paging information
  427. pagingSupported        dw    ?    ; not implemented yet
  428. curPage            dw    ?    ; not implemented yet
  429. maxPage            dw    ?    ; not implemented yet
  430. ;*** Force (image width MOD imageWideAdjust) = 0.
  431. imageWideAdjust        dw    ?    ; not implemented yet
  432. ;*** Current and screen addresses
  433.     LABEL    inAddr    DWORD        ; current input address
  434. inOff    dw    0
  435. inSeg    dw    0A000h
  436.     LABEL    outAddr    DWORD        ; current output address
  437. outOff    dw    0
  438. outSeg    dw    0A000h
  439.     LABEL    scrAddr    DWORD        ; screen address
  440. scrOff    dw    0
  441. scrSeg    dw    0A000h
  442. ;*** Copyright string
  443.     db    'The Graphics Engine -- Copyright (c) 1993 by Matthew Hildebrand'
  444.  
  445.  
  446. inited        db    0
  447. colourPalette    db    768    DUP(?)
  448. lineOffs    dw    SCREEN_DEEP    DUP(?)
  449. bankNum        dw    SCREEN_DEEP    DUP(?)
  450. bankChanges    dw    SCREEN_DEEP    DUP(?)
  451. curBank        dw    ?
  452. screenWide    dw    ?
  453.  
  454. bankadr        dw    OFFSET _nobank
  455. vgamem        dw    ?
  456. bksize        dw    ?
  457. bksizeShl10Dec    dw    ?
  458. retval        dw    ?        ; first return value from whichVGA()
  459. scanline    dw    ?
  460.  
  461. aheada        dw    ?
  462. aheadb        dw    ?
  463. ativga        dw    ?
  464. chipstech     dw    ?
  465. everex        dw    ?
  466. genoa        dw    ?
  467. ncr        dw    ?
  468. oak067        dw    ?
  469. paradise     dw    ?
  470. trident        dw    ?
  471. t8900        dw    ?
  472. tseng        dw    ?
  473. tseng4        dw    ?
  474. video7        dw    ?
  475. vesa        dw    ?
  476.  
  477.  
  478. ; VESA information
  479.     STRUC    vgainfo
  480. VESASignature    db    4 dup (?)    ; 4 signature bytes
  481. VESAVersion    dw    ?        ; VESA version number
  482. OEMStringPtr    dd    ?        ; Pointer to OEM string
  483. Capabilities    db    4 dup (?)    ; Capabilities of the video environment
  484. VideoModePtr    dd    ?        ; Pointer to supported Super VGA modes
  485.     ENDS
  486.     STRUC    vesamode
  487. ModeAttributes    dw    ?    ; mode attributes
  488. WinAAttributes    db    ?    ; window A attributes
  489. WinBAttributes    db    ?    ; window B attributes
  490. WinGranularity    dw    ?    ; window granularity
  491. WinSize        dw    ?    ; window size
  492. WinASegment    dw    ?    ; window A start segment
  493. WinBSegment    dw    ?    ; window B start segment
  494. WinFuncPtr    dd    ?    ; pointer to window function
  495. BytesPerLine    dw    ?    ; bytes per scan line
  496. ;
  497. ; optional information (provided if bit D1 of ModeAttributes is set)
  498. ;
  499. XResolution    dw    ?    ; horizontal resolution
  500. YResolution    dw    ?    ; vertical resolution
  501. XCharSize    db    ?    ; character cell width
  502. YCharSize    db    ?    ; character cell height
  503. NumberOfPlanes    db    ?    ; number of memory planes
  504. BitsPerPixel    db    ?    ; bits per pixel
  505. NumberOfBanks    db    ?    ; number of banks
  506. MemoryModel    db    ?    ; memory model type
  507. BankSize    db    ?    ; bank size in kb
  508.     db    227    DUP(?)    ; pad to 256 bytes
  509.     ENDS
  510.  
  511. vesabuf        db    256    DUP(?)
  512. modebuf        vesamode    ?
  513.  
  514.  
  515. MACRO    NEWBANK
  516.   call    [bankadr]
  517. ENDM
  518.  
  519.  
  520. ;*****
  521. ;***** initGraphics
  522. ;*****
  523.  
  524. PROC    C    initGraphics
  525.   cmp    [inited],0
  526.   je    @@NotInited
  527.   call    setMode
  528.   mov    ax,1
  529.   retf
  530.  
  531.     @@NotInited:
  532.   call    whichVGA
  533.   or    ax,ax                ; was function successful
  534.   jz    @@Error                ; no, quit
  535.   call    setMode
  536.   or    ax,ax                ; was function successful?
  537.   jz    @@Error                ; no, quit
  538.   call    makeAddrTable
  539.  
  540.   cmp    [vgamem],512            ; ensure enough memory
  541.   jb    @@Error                ; abort if <512 K of video RAM
  542.  
  543.   mov    ax,[bksize]            ; initialize bksizeShl10Dec
  544.   shl    ax,10                ; shift it
  545.   dec    ax                ; decrement it
  546.   mov    [bksizeShl10Dec],ax        ; store it
  547.  
  548.   mov    ax,1
  549.   mov    [inited],al
  550.   retf
  551.  
  552.     @@Error:
  553.   xor    ax,ax
  554.   retf
  555. ENDP
  556.  
  557.  
  558. ;*****
  559. ;***** putLine
  560. ;*****
  561.  
  562. PROC    C    putLine_scr_copy
  563.     ARG    lineNum:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  564.   push    ds si di
  565.  
  566.   cld
  567.   mov    bx,[lineNum]            ; Decide if bank changes mid-line
  568.   shl    bx,1
  569.   cmp    [cs:bankChanges+bx],0
  570.   jne    @@BankChanged
  571.  
  572.   mov    ax,[cs:bankNum+bx]
  573.   cmp    ax,[curBank]            ; set bank only if necessary
  574.   je    @@NoNewBank
  575.   NEWBANK
  576.  
  577.     @@NoNewBank:
  578.   mov    cx,[lineLen]            ; blast the line into video memory
  579.   mov    ax,0A000h
  580.   mov    es,ax
  581.   mov    di,[cs:lineOffs+bx]
  582.   add    di,[xOff]
  583.   lds    si,[buf]
  584.   shr    cx,1
  585.   rep    movsw
  586.   jnc    @@Exit
  587.   movsb
  588.     @@Exit:
  589.   pop    di si ds
  590.   leave
  591.   retf
  592.  
  593.     @@BankChanged:                  ; slow pixel-by-pixel
  594.   mov    cx,[lineLen]
  595.   mov    dx,[lineNum]
  596.   mov    bx,[xOff]
  597.   lds    si,[buf]
  598.     @@Loop:
  599.   lodsb
  600.   push    bx cx dx si
  601.   call    far putPixel_scr_copy C,bx,dx,ax
  602.   pop    si dx cx bx
  603.   inc    bx
  604.   loop    @@Loop
  605.  
  606.   pop    di si ds
  607.   leave
  608.   retf
  609. ENDP
  610.  
  611. PROC    C    putLine_mem_copy
  612.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  613.   push    ds si di            ; save these registers
  614.  
  615.   xor    eax,eax                ; clear EAX
  616.   xor    edx,edx                ; clear EDX
  617.   xor    edi,edi                ; clear EDI
  618.  
  619.   les    di,[outAddr]            ; load output address
  620.   mov    ax,[y]
  621.   mov    dx,[outScreenWide]
  622.   mul    edx                    ; EDX:EAX = offset - EDI - x
  623.   add    edi,eax                ; EDI = offset - x
  624.   mov    dx,[xOff]
  625.   add    edi,edx                ; EDI = offset
  626.   mov    edx,edi                ; EDX = offset
  627.   shr    edx,4                ; EDX = # of paragraphs (segments)
  628.   add    dx,[outSeg]            ; DX = new segment
  629.   mov    es,dx                ; ES = new segment
  630.   and    di,0000000000001111b             ; DI = offset within new segment
  631.  
  632.   lds    si,[buf]            ; load input address
  633.   mov    dx,si                ; DX = offset
  634.   shr    dx,4                ; DX = # of paragraphs (segments)
  635.   mov    ax,ds                ; AX = DS
  636.   add    ax,dx                ; AX = new DS
  637.   mov    ds,ax                ; DS = new DS
  638.   and    si,0000000000001111b        ; SI = offset within new segment
  639.  
  640.   cld
  641.   mov    cx,[lineLen]            ; CX = line length
  642.   mov    dx,cx                ; DX = line length
  643.   shr    cx,2                ; CX = line length in dwords
  644.   rep    movsd                     ; move the dwords if necessary
  645.   mov    cx,dx                ; CX = line length in bytes
  646.   and    cx,0000000000000011b        ; CX = any residual bytes
  647.   rep    movsb                ; move the bytes if necessary
  648.  
  649.   pop    di si ds            ; restore registers
  650.   leave                    ; clean up
  651.   retf                    ; return
  652. ENDP
  653.  
  654.  
  655. ;*****
  656. ;***** getLine
  657. ;*****
  658.  
  659. PROC    C    getLine_scr
  660.     ARG    lineNum:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  661.   push    ds si di
  662.  
  663.   cld
  664.   mov    bx,[lineNum]            ; Decide if bank changes mid-line
  665.   shl    bx,1
  666.   cmp    [cs:bankChanges+bx],0
  667.   jne    @@BankChanged
  668.  
  669.   mov    ax,[cs:bankNum+bx]
  670.   cmp    ax,[curBank]            ; set bank only if necessary
  671.   je    @@NoNewBank
  672.   NEWBANK
  673.  
  674.     @@NoNewBank:
  675.   mov    cx,[lineLen]            ; blast the line into video memory
  676.   mov    ax,0A000h
  677.   mov    ds,ax
  678.   mov    si,[cs:lineOffs+bx]
  679.   add    si,[xOff]
  680.   les    di,[buf]
  681.   shr    cx,1
  682.   rep    movsw
  683.   jnc    @@Exit
  684.   movsb
  685.     @@Exit:
  686.   pop    di si ds
  687.   leave
  688.   retf
  689.  
  690.     @@BankChanged:                  ; slow pixel-by-pixel
  691.   mov    cx,[lineLen]
  692.   mov    dx,[lineNum]
  693.   mov    bx,[xOff]
  694.   les    di,[buf]
  695.     @@Loop:
  696.   push    bx cx dx di es
  697.   call    far getPixel_scr C,bx,dx
  698.   pop    es di dx cx bx
  699.   stosb
  700.   inc    bx
  701.   loop    @@Loop
  702.  
  703.   pop    di si ds
  704.   leave
  705.   retf
  706. ENDP
  707.  
  708. PROC    C    getLine_mem
  709.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  710.   push    ds si di            ; save these registers
  711.  
  712.   xor    eax,eax                ; clear EAX
  713.   xor    edx,edx                ; clear EDX
  714.   xor    esi,esi                ; clear ESI
  715.  
  716.   les    si,[inAddr]            ; load input address
  717.   mov    ax,[y]
  718.   mov    dx,[inScreenWide]
  719.   mul    edx                    ; EDX:EAX = offset - ESI - x
  720.   add    esi,eax                ; ESI = offset - x
  721.   mov    dx,[xOff]
  722.   add    esi,edx                ; ESI = offset
  723.   mov    edx,esi                ; EDX = offset
  724.   shr    edx,4                ; EDX = # of paragraphs (segments)
  725.   add    dx,[inSeg]            ; DX = new segment
  726.   mov    ds,dx                ; ES = new segment
  727.   and    si,0000000000001111b             ; SI = offset within new segment
  728.  
  729.   les    di,[buf]            ; load output address
  730.   mov    dx,di                ; DX = offset
  731.   shr    dx,4                ; DX = # of paragraphs (segments)
  732.   mov    ax,es                ; AX = ES
  733.   add    ax,dx                ; AX = new ES
  734.   mov    es,ax                ; ES = new ES
  735.   and    di,0000000000001111b        ; DI = offset within new segment
  736.  
  737.   cld
  738.   mov    cx,[lineLen]            ; CX = line length
  739.   mov    dx,cx                ; DX = line length
  740.   shr    cx,2                ; CX = line length in dwords
  741.   rep    movsd                     ; move the dwords if necessary
  742.   mov    cx,dx                ; CX = line length in bytes
  743.   and    cx,0000000000000011b        ; CX = any residual bytes
  744.   rep    movsb                ; move the bytes if necessary
  745.  
  746.   pop    di si ds            ; restore registers
  747.   leave                    ; clean up
  748.   retf                    ; return
  749. ENDP
  750.  
  751.  
  752. ;*****
  753. ;***** putPixel
  754. ;*****
  755.  
  756. ; Copy a pixel to the screen
  757. PROC    C    putPixel_scr_copy
  758.     ARG    x:WORD, y:WORD, colour:BYTE
  759.   mov    bx,[y]                ; BX = y coordinate
  760.   shl    bx,1                ; to access a table of words
  761.   mov    ax,[cs:bankNum+bx]        ; AX = bank at start of line
  762.   mov    bx,[cs:lineOffs+bx]        ; DX = offset at start of line
  763.   add    bx,[x]                ; BX = offset of pixel
  764.   adc    ax,0                ; in case of overflow, inc AX
  765.   mov    dx,[bksizeShl10Dec]        ; DX = bank size in bytes - 1
  766.   cmp    bx,dx                ; is offset > than bank size
  767.   jbe    @@offsetOK            ; no, proceed
  768.  
  769.   sub    bx,dx                ; BX = fixed offset
  770.   inc    ax                ; AX = new bank
  771.  
  772.     @@offsetOK:
  773.   cmp    ax,[curBank]
  774.   je    @@NoNew
  775.   NEWBANK                ; switch banks if a new bank entered
  776.     @@NoNew:
  777.   mov    ax,0A000h            ; setup screen segment A000
  778.   mov    es,ax
  779.   mov    al,[colour]            ; get color of pixel to plot
  780.   mov    [es:bx],al
  781.   leave
  782.   retf
  783. ENDP
  784.  
  785. ; Copy a pixel to memory
  786. PROC    C    putPixel_mem_copy
  787.     ARG    x:WORD,y:WORD,colour:BYTE
  788.   xor    eax,eax                ; clear EAX
  789.   xor    ebx,ebx                ; clear EBX
  790.   xor    edx,edx                ; clear EDX
  791.  
  792.   les    bx,[outAddr]            ; load output address
  793.   mov    ax,[y]
  794.   mov    dx,[outScreenWide]
  795.   mul    edx                    ; EDX:EAX = offset - EBX - x
  796.   add    ebx,eax                ; EBX = offset - x
  797.   mov    dx,[x]
  798.   add    ebx,edx                ; EBX = offset
  799.  
  800.   mov    edx,ebx                ; EDX = offset
  801.   shr    edx,4                ; EDX = # of paragraphs (segments)
  802.   add    dx,[outSeg]            ; DX = new segment
  803.   mov    es,dx                ; ES = new segment
  804.   and    bx,0000000000001111b             ; BX = offset within new segment
  805.  
  806.   mov    al,[colour]            ; colour in AL
  807.   mov    [es:bx],al            ; store pixel
  808.   leave                    ; clean up
  809.   retf                    ; return
  810. ENDP
  811.  
  812. ; AND a pixel to memory
  813. PROC    C    putPixel_mem_and
  814.     ARG    x:WORD,y:WORD,colour:BYTE
  815.   xor    eax,eax                ; clear EAX
  816.   xor    ebx,ebx                ; clear EBX
  817.   xor    edx,edx                ; clear EDX
  818.  
  819.   les    bx,[outAddr]            ; load output address
  820.   mov    ax,[y]
  821.   mov    dx,[outScreenWide]
  822.   mul    edx                    ; EDX:EAX = offset - EBX - x
  823.   add    ebx,eax                ; EBX = offset - x
  824.   mov    dx,[x]
  825.   add    ebx,edx                ; EBX = offset
  826.  
  827.   mov    edx,ebx                ; EDX = offset
  828.   shr    edx,4                ; EDX = # of paragraphs (segments)
  829.   add    dx,[outSeg]            ; DX = new segment
  830.   mov    es,dx                ; ES = new segment
  831.   and    bx,0000000000001111b             ; BX = offset within new segment
  832.  
  833.   mov    al,[colour]            ; colour in AL
  834.   and    [es:bx],al            ; AND pixel
  835.   leave                    ; clean up
  836.   retf                    ; return
  837. ENDP
  838.  
  839. ; NOT a pixel to memory
  840. PROC    C    putPixel_mem_not
  841.     ARG    x:WORD,y:WORD,colour:BYTE
  842.   xor    eax,eax                ; clear EAX
  843.   xor    ebx,ebx                ; clear EBX
  844.   xor    edx,edx                ; clear EDX
  845.  
  846.   les    bx,[outAddr]            ; load output address
  847.   mov    ax,[y]
  848.   mov    dx,[outScreenWide]
  849.   mul    edx                    ; EDX:EAX = offset - EBX - x
  850.   add    ebx,eax                ; EBX = offset - x
  851.   mov    dx,[x]
  852.   add    ebx,edx                ; EBX = offset
  853.  
  854.   mov    edx,ebx                ; EDX = offset
  855.   shr    edx,4                ; EDX = # of paragraphs (segments)
  856.   add    dx,[outSeg]            ; DX = new segment
  857.   mov    es,dx                ; ES = new segment
  858.   and    bx,0000000000001111b             ; BX = offset within new segment
  859.  
  860.   mov    al,[colour]            ; colour in AL
  861.   not    al                ; NOT it
  862.   mov    [es:bx],al            ; store NOTed pixel
  863.   leave                    ; clean up
  864.   retf                    ; return
  865. ENDP
  866.  
  867. ; OR a pixel to memory
  868. PROC    C    putPixel_mem_or
  869.     ARG    x:WORD,y:WORD,colour:BYTE
  870.   xor    eax,eax                ; clear EAX
  871.   xor    ebx,ebx                ; clear EBX
  872.   xor    edx,edx                ; clear EDX
  873.  
  874.   les    bx,[outAddr]            ; load output address
  875.   mov    ax,[y]
  876.   mov    dx,[outScreenWide]
  877.   mul    edx                    ; EDX:EAX = offset - EBX - x
  878.   add    ebx,eax                ; EBX = offset - x
  879.   mov    dx,[x]
  880.   add    ebx,edx                ; EBX = offset
  881.  
  882.   mov    edx,ebx                ; EDX = offset
  883.   shr    edx,4                ; EDX = # of paragraphs (segments)
  884.   add    dx,[outSeg]            ; DX = new segment
  885.   mov    es,dx                ; ES = new segment
  886.   and    bx,0000000000001111b             ; BX = offset within new segment
  887.  
  888.   mov    al,[colour]            ; colour in AL
  889.   or    [es:bx],al            ; OR pixel
  890.   leave                    ; clean up
  891.   retf                    ; return
  892. ENDP
  893.  
  894. ; XOR a pixel to memory
  895. PROC    C    putPixel_mem_xor
  896.     ARG    x:WORD,y:WORD,colour:BYTE
  897.   xor    eax,eax                ; clear EAX
  898.   xor    ebx,ebx                ; clear EBX
  899.   xor    edx,edx                ; clear EDX
  900.  
  901.   les    bx,[outAddr]            ; load output address
  902.   mov    ax,[y]
  903.   mov    dx,[outScreenWide]
  904.   mul    edx                    ; EDX:EAX = offset - EBX - x
  905.   add    ebx,eax                ; EBX = offset - x
  906.   mov    dx,[x]
  907.   add    ebx,edx                ; EBX = offset
  908.  
  909.   mov    edx,ebx                ; EDX = offset
  910.   shr    edx,4                ; EDX = # of paragraphs (segments)
  911.   add    dx,[outSeg]            ; DX = new segment
  912.   mov    es,dx                ; ES = new segment
  913.   and    bx,0000000000001111b             ; BX = offset within new segment
  914.  
  915.   mov    al,[colour]            ; colour in AL
  916.   xor    [es:bx],al            ; XOR pixel
  917.   leave                    ; clean up
  918.   retf                    ; return
  919. ENDP
  920.  
  921.  
  922. ;*****
  923. ;***** getPixel
  924. ;*****
  925.  
  926. ; Get a pixel from the screen
  927. PROC    C    getPixel_scr
  928.     ARG    x:WORD, y:WORD
  929.   mov    bx,[y]                ; BX = y coordinate
  930.   shl    bx,1                ; to access a table of words
  931.   mov    ax,[cs:bankNum+bx]        ; AX = bank at start of line
  932.   mov    bx,[cs:lineOffs+bx]        ; DX = offset at start of line
  933.   add    bx,[x]                ; BX = offset of pixel
  934.   adc    ax,0                ; in case of overflow, inc AX
  935.   mov    dx,[bksizeShl10Dec]        ; DX = bank size in bytes - 1
  936.   cmp    bx,dx                ; is offset > than bank size
  937.   jb    @@offsetOK            ; no, proceed
  938.  
  939.   sub    bx,dx                ; BX = fixed offset
  940.   inc    ax                ; AX = new bank
  941.  
  942.     @@offsetOK:
  943.   cmp    ax,[curBank]
  944.   je    @@NoNew
  945.   NEWBANK                ; switch banks if a new bank entered
  946.     @@NoNew:
  947.   mov    ax,0A000h            ; setup screen segment A000
  948.   mov    es,ax
  949.   mov    al,[es:bx]            ; AL = colour for return
  950.   leave
  951.   retf
  952. ENDP
  953.  
  954. ; Get a pixel from memory
  955. PROC    C    getPixel_mem
  956.     ARG    x:WORD,y:WORD
  957.   xor    eax,eax                ; clear EAX
  958.   xor    ebx,ebx                ; clear EBX
  959.   xor    edx,edx                ; clear EDX
  960.  
  961.   les    bx,[inAddr]            ; load input address
  962.   mov    ax,[y]
  963.   mov    dx,[inScreenWide]
  964.   mul    edx                    ; EDX:EAX = offset - EBX - x
  965.   add    ebx,eax                ; EBX = offset - x
  966.   mov    dx,[x]
  967.   add    ebx,edx                ; EBX = offset
  968.  
  969.   mov    edx,ebx                ; EDX = offset
  970.   shr    edx,4                ; EDX = # of paragraphs (segments)
  971.   add    dx,[inSeg]            ; DX = new segment
  972.   mov    es,dx                ; ES = new segment
  973.   and    bx,0000000000001111b             ; BX = offset within new segment
  974.  
  975.   xor    ax,ax                ; clear AX
  976.   mov    al,[es:bx]            ; store pixel in AX for return
  977.   leave                    ; clean up
  978.   retf                    ; return
  979. ENDP
  980.  
  981.  
  982. ;*****
  983. ;***** horizLine
  984. ;*****
  985.  
  986. PROC    C    horizLine_scr_copy
  987.     ARG    y:WORD, x1:WORD, x2:WORD, colour:BYTE
  988.   push    di
  989.  
  990.   cld
  991.   mov    bx,[y]                ; Decide if bank changes mid-line
  992.   shl    bx,1
  993.   cmp    [cs:bankChanges+bx],0
  994.   jne    @@BankChanged
  995.  
  996.   mov    ax,[cs:bankNum+bx]
  997.   cmp    ax,[curBank]            ; set bank only if necessary
  998.   je    @@NoNewBank
  999.   NEWBANK
  1000.  
  1001.     @@NoNewBank:
  1002.   mov    ax,0A000h
  1003.   mov    es,ax
  1004.   mov    ax,[x1]
  1005.   mov    di,[cs:lineOffs+bx]
  1006.   add    di,ax
  1007.   mov    cx,[x2]                ; blast the line into video memory
  1008.   inc    cx
  1009.   sub    cx,ax
  1010.   mov    al,[colour]
  1011.   mov    ah,al
  1012.   shr    cx,1
  1013.   rep    stosw
  1014.   jnc    @@Exit
  1015.   stosb
  1016.  
  1017.     @@Exit:
  1018.   pop    di
  1019.   leave
  1020.   retf
  1021.  
  1022.     @@BankChanged:                  ; slow pixel-by-pixel
  1023.   mov    bx,[x1]
  1024.   mov    cx,[x2]
  1025.   inc    cx
  1026.   sub    cx,bx
  1027.   mov    dx,[y]
  1028.     @@Loop:
  1029.   push    bx cx dx
  1030.   mov    al,[colour]
  1031.   call    far putPixel_scr_copy C,bx,dx,ax
  1032.   pop    dx cx bx
  1033.   inc    bx
  1034.   loop    @@Loop
  1035.  
  1036.   pop    di
  1037.   leave
  1038.   retf
  1039. ENDP
  1040.  
  1041. PROC    C    horizLine_mem_copy
  1042.     ARG    y:WORD, x1:WORD, x2:WORD, colour:BYTE
  1043.   push    edi                ; store EDI
  1044.  
  1045.   xor    eax,eax                ; clear EAX
  1046.   xor    edi,edi                ; clear EDI
  1047.   xor    edx,edx                ; clear EDX
  1048.  
  1049.   les    di,[outAddr]            ; load output address
  1050.   mov    ax,[y]
  1051.   mov    dx,[outScreenWide]
  1052.   mul    edx                    ; EDX:EAX = offset - EDI - x
  1053.   add    edi,eax                ; EDI = offset - x
  1054.   mov    dx,[x1]
  1055.   add    edi,edx                ; EDI = offset
  1056.   mov    edx,edi                ; EDX = offset
  1057.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1058.   add    dx,[outSeg]            ; DX = new segment
  1059.   mov    es,dx                ; ES = new segment
  1060.   and    di,0000000000001111b             ; DI = offset within new segment
  1061.  
  1062.   mov    al,[colour]            ; colour in AL
  1063.   mov    ah,al                ; colour in AH
  1064.   mov    bx,ax
  1065.   shl    eax,16
  1066.   mov    ax,bx                 ; colour in each byte of EAX
  1067.  
  1068.   mov    cx,[x2]
  1069.   sub    cx,[x1]
  1070.   inc    cx                ; CX = line length in pixels
  1071.   mov    dx,cx                ; DX = line length in bytes
  1072.  
  1073.   shr    cx,2                ; CX = line length in dwords
  1074.   rep    stosd                ; store four bytes at a time
  1075.   mov    cx,dx                ; CX = line length in pixels
  1076.   and    cx,0000000000000011b        ; CX = any remaining bytes
  1077.   rep    stosb                ; store the remaining bytes
  1078.  
  1079.   pop    edi                    ; restore EDI
  1080.   leave                    ; clean up
  1081.   retf                    ; return
  1082. ENDP
  1083.  
  1084.  
  1085. ;*****
  1086. ;***** setPaletteReg
  1087. ;*****
  1088.  
  1089. PROC    C    setPaletteReg
  1090.     ARG    palNum:WORD,red:BYTE,green:BYTE,blue:BYTE
  1091.   mov    bx,[palNum]
  1092.  
  1093.   mov    dx,3C8h                ; set for correct palette register
  1094.   mov    ax,[palNum]
  1095.   out    dx,al
  1096.   inc    dx
  1097.  
  1098.   mov    al,[red]            ; red
  1099.   shr    al,2
  1100.   jnc    @@L1
  1101.   cmp    al,63
  1102.   je    @@L1
  1103.   inc    al
  1104.     @@L1:
  1105.   out    dx,al
  1106.  
  1107.   mov    al,[green]            ; green
  1108.   shr    al,2
  1109.   jnc    @@L2
  1110.   cmp    al,63
  1111.   je    @@L2
  1112.   inc    al
  1113.     @@L2:
  1114.   out    dx,al
  1115.  
  1116.   mov    al,[blue]            ; blue
  1117.   shr    al,2
  1118.   jnc    @@L3
  1119.   cmp    al,63
  1120.   je    @@L3
  1121.   inc    al
  1122.     @@L3:
  1123.   out    dx,al
  1124.  
  1125.   leave
  1126.   retf
  1127. ENDP
  1128.  
  1129.  
  1130. ;*****
  1131. ;***** getPaletteReg
  1132. ;*****
  1133.  
  1134. PROC    C    getPaletteReg
  1135.     ARG    palNum:WORD,red:DATAPTR,green:DATAPTR,blue:DATAPTR
  1136.   push    ds si
  1137.  
  1138.   mov    dx,3C7h                ; set for correct palette register
  1139.   mov    ax,[palNum]
  1140.   out    dx,al
  1141.   mov    dx,3C9h
  1142.  
  1143.   in    al,dx                ; red
  1144.   lds    si,[red]
  1145.   shl    al,2
  1146.   mov    [ds:si],al
  1147.   in    al,dx                ; green
  1148.   lds    si,[green]
  1149.   shl    al,2
  1150.   mov    [ds:si],al
  1151.   in    al,dx                ; blue
  1152.   lds    si,[blue]
  1153.   shl    al,2
  1154.   mov    [ds:si],al
  1155.  
  1156.   pop    si ds
  1157.   leave
  1158.   retf
  1159. ENDP
  1160.  
  1161.  
  1162. ;*****
  1163. ;***** setBlockPalette
  1164. ;*****
  1165.  
  1166. PROC    C    setBlockPalette
  1167.     ARG    firstReg:WORD,lastReg:WORD,paletteData:DATAPTR
  1168.   push    ds si
  1169.  
  1170.   lds    si,[paletteData]        ; set up
  1171.   mov    dx,3C8h
  1172.   mov    ax,[firstReg]
  1173.   out    dx,al
  1174.   inc    dx
  1175.   mov    cx,[lastReg]            ; CX = number of registers
  1176.   sub    cx,ax
  1177.   inc    cx
  1178.   cld
  1179.  
  1180.     @@LLoop:
  1181.   lodsb            ; red
  1182.   shr    al,2
  1183.   jnc    @@L1
  1184.   cmp    al,63
  1185.   je    @@L1
  1186.   inc    al
  1187.     @@L1:
  1188.   out    dx,al
  1189.  
  1190.   lodsb            ; green
  1191.   shr    al,2
  1192.   jnc    @@L2
  1193.   cmp    al,63
  1194.   je    @@L2
  1195.   inc    al
  1196.     @@L2:
  1197.   out    dx,al
  1198.  
  1199.   lodsb            ; blue
  1200.   shr    al,2
  1201.   jnc    @@L3
  1202.   cmp    al,63
  1203.   je    @@L3
  1204.   inc    al
  1205.     @@L3:
  1206.   out    dx,al
  1207.  
  1208.   loop    @@LLoop
  1209.  
  1210.     @@LExit:
  1211.   pop    si ds
  1212.   leave
  1213.   retf
  1214. ENDP
  1215.  
  1216.  
  1217. ;*****
  1218. ;***** getBlockPalette
  1219. ;*****
  1220.  
  1221. PROC    C    getBlockPalette
  1222.     ARG    firstReg:WORD,lastReg:WORD,paletteData:DATAPTR
  1223.   push    di
  1224.  
  1225.   les    di,[paletteData]        ; set up
  1226.   mov    dx,3C7h
  1227.   mov    ax,[firstReg]
  1228.   out    dx,al
  1229.   mov    dx,3C9h
  1230.   mov    cx,[lastReg]            ; CX = number of registers
  1231.   sub    cx,ax
  1232.   inc    cx
  1233.   cld
  1234.  
  1235.     @@L1:
  1236.   in    al,dx
  1237.   shl    al,2
  1238.   stosb            ; red
  1239.   in    al,dx
  1240.   shl    al,2
  1241.   stosb            ; green
  1242.   in    al,dx
  1243.   shl    al,2
  1244.   stosb            ; blue
  1245.   loop    @@L1
  1246.  
  1247.     @@LExit:
  1248.   pop    di
  1249.   leave
  1250.   retf
  1251. ENDP
  1252.  
  1253.  
  1254. ;*****
  1255. ;***** Bank switching routines
  1256. ;*****
  1257.  
  1258. _aheada:                ; Ahead Systems Ver A
  1259.   push    ax dx cx
  1260.   cli
  1261.   mov    [curBank],ax
  1262.   mov    ch,al
  1263.   mov    dx,3CEh            ; Enable extended registers
  1264.   mov    ax,200Fh
  1265.   out    dx,ax
  1266.   mov    dl,0CCh            ; bit 0
  1267.   in    al,dx
  1268.   mov    dl,0C2h
  1269.   and    al,11011111b
  1270.   shr    ch,1
  1271.   jnc    @@skpa
  1272.   or    al,00100000b
  1273.     @@skpa:
  1274.   out    dx,al
  1275.   mov    dl,0CFh            ; bits 1,2,3
  1276.   xor    al,al
  1277.   out    dx,al
  1278.   inc    dx
  1279.   in    al,dx
  1280.   dec    dx
  1281.   and    al,11111000b
  1282.   or    al,ch
  1283.   mov    ah,al
  1284.   xor    al,al
  1285.   out    dx,ax
  1286.   sti
  1287.   pop    cx dx ax
  1288.   ret
  1289.  
  1290. _aheadb:                ; Ahead Systems Ver B
  1291.   push    ax dx cx
  1292.   cli
  1293.   mov    [curBank],ax
  1294.   mov    ch,al
  1295.   mov    dx,3CEh            ; Enable extended registers
  1296.   mov    ax,200Fh
  1297.   out    dx,ax
  1298.   mov    ah,ch
  1299.   mov    cl,4
  1300.   shl    ah,cl
  1301.   or    ah,ch
  1302.   mov    al,0Dh
  1303.   out    dx,ax
  1304.   sti
  1305.   pop    cx dx ax
  1306.   ret
  1307.  
  1308. _ativga:                ; ATI VGA Wonder
  1309.   push    ax dx
  1310.   cli
  1311.   mov    [curBank],ax
  1312.   mov    ah,al
  1313.   mov    dx,1CEh
  1314.   mov    al,0B2h
  1315.   out    dx,al
  1316.   inc    dl
  1317.   in    al,dx
  1318.   shl    ah,1
  1319.   and    al,0E1h
  1320.   or    ah,al
  1321.   mov    al,0B2h
  1322.   dec    dl
  1323.   out    dx,ax
  1324.   sti
  1325.   pop    dx ax
  1326.   ret
  1327.  
  1328. _chipstech:                ; Chips & Tech
  1329.   push    ax dx ax
  1330.   cli
  1331.   mov    [curBank],ax
  1332.   mov    dx,46E8h        ; place chip in setup mode
  1333.   mov    ax,1Eh
  1334.   out    dx,ax
  1335.   mov    dx,103h            ; enable extended registers
  1336.   mov    ax,0080h
  1337.   out    dx,ax
  1338.   mov    dx,46E8h        ; bring chip out of setup mode
  1339.   mov    ax,0Eh
  1340.   out    dx,ax
  1341.   pop    ax
  1342.   mov    ah,al
  1343.   mov    al,10h
  1344.   mov    dx,3D6h
  1345.   out    dx,ax
  1346.   sti
  1347.   pop    dx ax
  1348.   ret
  1349.  
  1350. _everex:                ; Everex
  1351.   push    ax dx cx
  1352.   cli
  1353.   mov    [curBank],ax
  1354.   mov    cl,al
  1355.   mov    dx,3C4h
  1356.   mov    al,8
  1357.   out    dx,al
  1358.   inc    dl
  1359.   in    al,dx
  1360.   dec    dl
  1361.   shl    al,1
  1362.   shr    cl,1
  1363.   rcr    al,1
  1364.   mov    ah,al
  1365.   mov    al,8
  1366.   out    dx,ax
  1367.   mov    dl,0CCh
  1368.   in    al,dx
  1369.   mov    dl,0C2h
  1370.   and    al,0DFh
  1371.   shr    cl,1
  1372.   jc    @@nob2
  1373.   or    al,20h
  1374.       @@nob2:
  1375.   out    dx,al
  1376.   sti
  1377.   pop    cx dx ax
  1378.   ret
  1379.  
  1380. _genoa:                    ; GENOA GVGA
  1381.   push    ax dx
  1382.   cli
  1383.   mov    [curBank],ax
  1384.   mov    ah,al
  1385.   shl    al,3
  1386.   or    ah,al
  1387.   mov    al,6
  1388.   or    ah,40h
  1389.   mov    dx,3C4h
  1390.   out    dx,ax
  1391.   sti
  1392.   pop    dx ax
  1393.   ret
  1394.  
  1395. _ncr:                    ; NCR 77C22E
  1396.   push    ax dx
  1397.   cli
  1398.   mov    [curBank],ax
  1399.   mov    ah,al
  1400.   mov    al,18h
  1401.   mov    dx,3C4h
  1402.   out    dx,ax
  1403.   mov    ax,19h
  1404.   out    dx,ax
  1405.   sti
  1406.   pop    dx ax
  1407.   ret
  1408.  
  1409. _oak067:                ; Oak Technology Inc OTI-067
  1410.   push    ax dx
  1411.   cli
  1412.   mov    [curBank],ax
  1413.   and    al,15
  1414.   mov    ah,al
  1415.   shl    al,4
  1416.   or    ah,al
  1417.   mov    al,11h
  1418.   mov    dx,3DEh
  1419.   out    dx,ax
  1420.   sti
  1421.   pop    dx ax
  1422.   ret
  1423.  
  1424. _paradise:                ; Paradise
  1425.   push    ax dx ax
  1426.   cli
  1427.   mov    [curBank],ax
  1428.   mov    dx,3CEh
  1429.   mov    ax,50Fh            ; turn off write protect on VGA registers
  1430.   out    dx,ax
  1431.   pop    ax
  1432.   mov    ah,al
  1433.   mov    al,9
  1434.   out    dx,ax
  1435.   sti
  1436.   pop    dx ax
  1437.   ret
  1438.  
  1439. _trident:                ; Trident
  1440.   push    ax dx ax
  1441.   cli
  1442.   mov    [curBank],ax
  1443.   mov    dx,3CEh            ; set pagesize to 64k
  1444.   mov    al,6
  1445.   out    dx,al
  1446.   inc    dl
  1447.   in    al,dx
  1448.   dec    dl
  1449.   or    al,4
  1450.   mov    ah,al
  1451.   mov    al,6
  1452.   out    dx,ax
  1453.  
  1454.   mov    dl,0C4h            ; switch to BPS mode
  1455.   mov    al,0Bh
  1456.   out    dx,al
  1457.   inc    dl
  1458.   in    al,dx
  1459.   dec    dl
  1460.  
  1461.   pop    ax
  1462.   mov    ah,al
  1463.   xor    ah,2
  1464.   mov    dx,3C4h
  1465.   mov    al,0Eh
  1466.   out    dx,ax
  1467.   sti
  1468.   pop    dx ax
  1469.   ret
  1470.  
  1471. _tseng:                    ; Tseng
  1472.   push    ax dx
  1473.   cli
  1474.   mov    [curBank],ax
  1475.   and    al,7
  1476.   mov    ah,al
  1477.   shl    al,3
  1478.   or    al,ah
  1479.   or    al,01000000b
  1480.   mov    dx,3CDh
  1481.   out    dx,al
  1482.   sti
  1483.   pop    dx ax
  1484.   ret
  1485.  
  1486. _tseng4:                ; Tseng 4000 series
  1487.   push    ax dx
  1488.   cli
  1489.   mov    [curBank],ax
  1490.   mov    ah,al
  1491.   mov    dx,3BFh            ; Enable access to extended registers
  1492.   mov    al,3
  1493.   out    dx,al
  1494.   mov    dl,0D8h
  1495.   mov    al,0A0h
  1496.   out    dx,al
  1497.   and    ah,15
  1498.   mov    al,ah
  1499.   shl    al,4
  1500.   or    al,ah
  1501.   mov    dl,0CDh
  1502.   out    dx,al
  1503.   sti
  1504.   pop    dx ax
  1505.   ret
  1506.  
  1507. _video7:                ; Video 7
  1508.   push    ax dx cx
  1509.   cli
  1510.   mov    [curBank],ax
  1511.   and    ax,15
  1512.   mov    ch,al
  1513.   mov    dx,3C4h
  1514.   mov    ax,0EA06h
  1515.   out    dx,ax
  1516.   mov    ah,ch
  1517.   and    ah,1
  1518.   mov    al,0F9h
  1519.   out    dx,ax
  1520.   mov    al,ch
  1521.   and    al,1100b
  1522.   mov    ah,al
  1523.   shr    ah,2
  1524.   or    ah,al
  1525.   mov    al,0F6h
  1526.   out    dx,al
  1527.   inc    dx
  1528.   in    al,dx
  1529.   dec    dx
  1530.   and    al,NOT 1111b
  1531.   or    ah,al
  1532.   mov    al,0F6h
  1533.   out    dx,ax
  1534.   mov    ah,ch
  1535.   mov    cl,4
  1536.   shl    ah,cl
  1537.   and    ah,100000b
  1538.   mov    dl,0CCh
  1539.   in    al,dx
  1540.   mov    dl,0C2h
  1541.   and    al,NOT 100000b
  1542.   or    al,ah
  1543.   out    dx,al
  1544.   sti
  1545.   pop    cx dx ax
  1546.   ret
  1547.  
  1548. _vesa:                ; Vesa SVGA interface
  1549.   push    ax bx dx
  1550.   cli
  1551.   mov    [curBank],ax
  1552.   mov    dx,ax
  1553.   xor    bx,bx
  1554.   mov    ax,4F05h
  1555.   int    10h
  1556.   sti
  1557.   pop    dx bx ax
  1558.   ret
  1559.  
  1560. _nobank:
  1561.   cli
  1562.   mov    [curBank],ax
  1563.   sti
  1564.   ret
  1565.  
  1566.  
  1567. MACRO    BKADR    func
  1568.   mov    [func],1
  1569.   mov    [bankadr],OFFSET _&func
  1570. ENDM
  1571.  
  1572. MACRO    NOJMP
  1573.   local    lbl
  1574.   jmp    short    lbl
  1575.     lbl:
  1576. ENDM
  1577.  
  1578.  
  1579. PROC    whichVGA    NEAR
  1580.   push    si di
  1581.  
  1582.   cmp    [inited],1
  1583.   jne    @@goTest
  1584.   mov    ax,[retval]
  1585.   pop    di si
  1586.   ret
  1587.  
  1588.     @@goTest:
  1589.   mov    [bankadr],OFFSET _nobank    ; Initialize variables
  1590.   mov    [vgamem],256
  1591.   mov    [bksize],64
  1592.   xor    ax,ax
  1593.   mov    [curBank],ax
  1594.   mov    [aheada],ax
  1595.   mov    [aheadb],ax
  1596.   mov    [ativga],ax
  1597.   mov    [chipstech],ax
  1598.   mov    [everex],ax
  1599.   mov    [genoa],ax
  1600.   mov    [ncr],ax
  1601.   mov    [oak067],ax
  1602.   mov    [paradise],ax
  1603.   mov    [trident],ax
  1604.   mov    [t8900],ax
  1605.   mov    [tseng],ax
  1606.   mov    [tseng4],ax
  1607.   mov    [video7],ax
  1608.   mov    [vesa],ax
  1609.  
  1610.   mov    ax,cs                ; Test for VESA
  1611.   mov    es,ax
  1612.   mov    di,OFFSET vesabuf
  1613.   mov    ax,4F00h
  1614.   int    10h
  1615.   cmp    ax,004Fh
  1616.   jne    @@noVESA
  1617.   BKADR    vesa
  1618.   mov    [bksize],64            ; assume 64 K bank size (for now)
  1619.   mov    [vgamem],512            ; assume 512 K if VESA
  1620.   jmp    @@fini
  1621.  
  1622.     @@noVESA:
  1623.   mov    si,1
  1624.  
  1625.   mov    ax,0C000h            ; Test for ATI
  1626.   mov    es,ax
  1627.   cmp    [word ptr es:40h],'13'    ; ATI Signiture on the Video BIOS
  1628.   jnz    @@noATI
  1629.   BKADR    ativga
  1630.   mov    [bksize],64        ; 64K bank size
  1631.   mov    dx,[es:10h]        ; get value of ATI extended register
  1632.   mov    bl,[es:43h]        ; get value of ATI chip version
  1633.   cmp    bl,'3'
  1634.   jae    @@v6up            ; use different method to find memory size
  1635.   mov    al,0BBh
  1636.   cli
  1637.   out    dx,al
  1638.   inc    dx
  1639.   in    al,dx
  1640.   sti
  1641.   test    al,20h
  1642.   jz    @@no512
  1643.   mov    [vgamem],512
  1644.   jmp    short    @@no512
  1645.       @@v6up:
  1646.   mov    al,0B0h            ; method for newer ATIs
  1647.   cli
  1648.   out    dx,al
  1649.   inc    dx
  1650.   in    al,dx            ; get RAM size for versions 3-5
  1651.   sti
  1652.   test    al,10h            ; check if 256 K or 512 K
  1653.   jz    @@v7up
  1654.   mov    [vgamem],512
  1655.       @@v7up:
  1656.   cmp    bl,'4'            ; get RAM size for versions 4 & 5
  1657.   jb    @@no512
  1658.   test    al,8            ; check if version 5 chip has 1024 K
  1659.   jz    @@no512
  1660.   mov    [vgamem],1024
  1661.       @@no512:
  1662.   jmp    @@fini
  1663.  
  1664.     @@noATI:
  1665.   mov    ax,7000h            ; Test for Everex
  1666.   xor    bx,bx
  1667.   cld
  1668.   int    10h
  1669.   cmp    al,70h
  1670.   jnz    @@noEverex
  1671.   BKADR    everex
  1672.   mov    [bksize],64        ; 64 K bank size
  1673.   and    ch,11000000b        ; how much memory on board?
  1674.   jz    @@skp
  1675.   mov    [vgamem],512
  1676.      @@skp:            ; fall through for Everex boards using Trident or Tseng4000
  1677.  
  1678.     @@noEverex:
  1679.   mov    dx,3C4h                ; Test for NCR 77C22E
  1680.   mov    ax,0FF05h
  1681.   call    _isport2
  1682.   jnz    @@noNCR
  1683.   mov    ax,5                   ; Disable extended registers
  1684.   out    dx,ax
  1685.   mov    ax,0FF10h        ; Try to write to extended register 10
  1686.   call    _isport2        ; If it writes then not NCR
  1687.   jz    @@noNCR
  1688.   mov    ax,105h            ; Enable extended registers
  1689.   out    dx,ax
  1690.   mov    ax,0FF10h
  1691.   call    _isport2
  1692.   jnz    @@noNCR            ; If it does NOT write then not NCR
  1693.   BKADR    ncr
  1694.   mov    [bksize],16        ; 16 K bank size
  1695.   mov    [vgamem],512
  1696.   jmp    @@fini
  1697.  
  1698.     @@noNCR:
  1699.   mov    dx,3C4h                  ; Test for Trident
  1700.   mov    al,0Bh
  1701.   out    dx,al
  1702.   inc    dl
  1703.   in    al,dx
  1704.   and    al,0Fh
  1705.   cmp    al,06h
  1706.   ja    @@noTrident
  1707.   cmp    al,2
  1708.   jb       @@noTrident
  1709.   BKADR    trident            ; Trident found, at least 8800
  1710.   mov    [bksize],64
  1711.   cmp    al,3            ; is it 8900?
  1712.   jb    @@no8900        ; no
  1713.   mov    [t8900],1        ; yes
  1714.   mov    dx,3D5h
  1715.   mov    al,1Fh
  1716.   out    dx,al
  1717.   inc    dx
  1718.   in    al,dx
  1719.   and    al,3
  1720.   cmp    al,1
  1721.   jb    @@notmem
  1722.   mov    [vgamem],512
  1723.   je    @@notmem
  1724.   mov    [vgamem],1024
  1725.     @@notmem:
  1726.   jmp    @@fini
  1727.  
  1728.     @@no8900:
  1729.   mov    [vgamem],512
  1730.   jmp    @@fini
  1731.  
  1732.     @@noTrident:
  1733.   mov    ax,6F00h            ; Test for Video 7
  1734.   xor    bx,bx
  1735.   cld
  1736.   int    10h
  1737.   cmp    bx,'V7'
  1738.   jnz    @@noVideo7
  1739.   BKADR    video7
  1740.   mov    [bksize],64        ; 64 K bank size
  1741.   mov    ax,6F07h
  1742.   cld
  1743.   int    10h
  1744.   and    ah,7Fh
  1745.   cmp    ah,1
  1746.   jbe    @@skp2
  1747.   mov    [vgamem],512
  1748.     @@skp2:
  1749.   cmp    ah,3
  1750.   jbe    @@skp3
  1751.   mov    [vgamem],1024
  1752.     @@skp3:
  1753.   jmp    @@fini
  1754.  
  1755.     @@noVideo7:
  1756.   mov    dx,3D4h                ; Test for GENOA GVGA
  1757.   mov    ax,032Eh        ; check for Herchi Register
  1758.   call    _isport2
  1759.   jnz    @@noGenoa
  1760.   mov    dx,3C4h            ; check for memory segment register
  1761.   mov    ax,3F06h
  1762.   call    _isport2
  1763.   jnz    @@noGenoa
  1764.   BKADR    genoa
  1765.   mov    [bksize],64        ; 64 K bank size
  1766.   mov    [vgamem],512
  1767.   jmp    @@fini
  1768.  
  1769.     @@noGenoa:
  1770.   mov    dx,3CEh                ; Test for Paradise
  1771.   mov    al,9            ; check Bank switch register
  1772.   out    dx,al
  1773.   inc    dx
  1774.   in    al,dx
  1775.   dec    dx
  1776.   or    al,al
  1777.   jnz    @@noParadise
  1778.  
  1779.   mov    ax,50Fh            ; turn off write protect on VGA registers
  1780.   out    dx,ax
  1781.   mov    dx,OFFSET _paradise
  1782.   mov    cx,1
  1783.   call    _chkbk
  1784.   jc    @@noParadise        ; if bank 0 and 1 same not paradise
  1785.   BKADR    paradise
  1786.   mov    [bksize],4        ; 4 K bank size
  1787.   mov    dx,3CEh
  1788.   mov    al,0Bh            ; 512k detect from Bob Berry
  1789.   out    dx,al
  1790.   inc    dx
  1791.   in    al,dx
  1792.   test    al,80h            ; if top bit set then 512k
  1793.   jz    @@nop512
  1794.   mov    [vgamem],512
  1795.     @@nop512:
  1796.   jmp    @@fini
  1797.  
  1798.     @@noParadise:
  1799.   mov    ax,5F00h            ; Test for Chips & Tech
  1800.   xor    bx,bx
  1801.   cld
  1802.   int    10h
  1803.   cmp    al,5Fh
  1804.   jnz    @@noChipsTech
  1805.   BKADR    chipstech
  1806.   mov    [bksize],16        ; 16 K bank size
  1807.   cmp    bh,1
  1808.   jb    @@skp4
  1809.   mov    [vgamem],512
  1810.   cmp    bh,2
  1811.   jb    @@skp4
  1812.   mov    [vgamem],1024
  1813.     @@skp4:
  1814.   jmp    @@fini
  1815.  
  1816.     @@noChipsTech:
  1817.   xor    ch,ch                ; check for Tseng 4000 series
  1818.   mov    dx,3D4h
  1819.   mov    ax,0F33h
  1820.   call    _isport2
  1821.   jnz    @@noTseng4
  1822.   mov    ch,1
  1823.  
  1824.   mov    dx,3BFh            ; Enable access to extended registers
  1825.   mov    al,3
  1826.   out    dx,al
  1827.   mov    dx,3D8h
  1828.   mov    al,0A0h
  1829.   out    dx,al
  1830.   jmp    short @@yes4
  1831.  
  1832.     @@noTseng4:
  1833.   mov    dx,3D4h            ; Test for Tseng 3000 or 4000
  1834.   mov    ax,1F25h        ; is the Overflow High register there?
  1835.   call    _isport2
  1836.   jnz    @@noTseng
  1837.   mov    al,03Fh            ; bottom six bits only
  1838.   jmp    short @@yes3
  1839.     @@yes4:
  1840.   mov    al,0FFh
  1841.     @@yes3:
  1842.   mov    dx,3CDh            ; test bank switch register
  1843.   call    _isport1
  1844.   jnz    @@noTseng
  1845.   BKADR    tseng
  1846.   mov    [bksize],64        ; 64 K bank size
  1847.   or    ch,ch
  1848.   jnz    @@t4mem
  1849.   mov    [vgamem],512
  1850.   jmp    @@fini
  1851.  
  1852.     @@t4mem:
  1853.   mov    dx,3D4h            ; Tseng 4000 memory detect 1meg
  1854.   mov    al,37h
  1855.   out    dx,al
  1856.   inc    dx
  1857.   in    al,dx
  1858.   test    al,1000b        ; if using 64kx4 RAMs then no more than 256k
  1859.   jz    @@nomem
  1860.   and    al,3
  1861.   cmp    al,1            ; if 8 bit wide bus then only two 256kx4 RAMs
  1862.   jbe    @@nomem
  1863.   mov    [vgamem],512
  1864.   cmp    al,2            ; if 16 bit wide bus then four 256kx4 RAMs
  1865.   je    @@nomem
  1866.   mov    [vgamem],1024        ; full meg with eight 256kx4 RAMs
  1867.     @@nomem:
  1868.   BKADR    tseng4
  1869.   mov    [bksize],64        ; 64 K bank size
  1870.   jmp    @@fini
  1871.  
  1872.     @@noTseng:
  1873.   mov    dx,3CEh                ; Test for Above A or B chipsets
  1874.   mov    ax,200Fh
  1875.   out    dx,ax
  1876.   inc    dx
  1877.   NOJMP
  1878.   in    al,dx
  1879.   cmp    al,21h
  1880.   jz    @@verB
  1881.   cmp    al,20h
  1882.   jnz    @@noAbove
  1883.   BKADR    aheada
  1884.   mov    [bksize],64        ; 64 K bank size
  1885.   mov    [vgamem],512
  1886.   jmp    @@fini
  1887.     @@verB:
  1888.   BKADR    aheadb
  1889.   mov    [bksize],64        ; 64 K bank size
  1890.   mov    [vgamem],512
  1891.   jmp   @@fini
  1892.  
  1893.     @@noAbove:
  1894.   mov    dx,3DEh                ; Test for Oak Technology
  1895.   mov    ax,0FF11h        ; look for bank switch register
  1896.   call    _isport2
  1897.   jnz    @@fini
  1898.   BKADR    oak067
  1899.   mov    [bksize],64        ; 64 K bank size
  1900.   mov    al,0Dh
  1901.   out    dx,al
  1902.   inc    dx
  1903.   NOJMP
  1904.   in    al,dx
  1905.   test    al,11000000b
  1906.   jz    @@fini
  1907.   mov    [vgamem],512
  1908.   test    al,01000000b
  1909.   jz    @@fini
  1910.   mov    [vgamem],1024
  1911.   jmp    short    @@fini
  1912.  
  1913.       @@noSVGA:
  1914.   xor    si,si                ; set error flag
  1915.  
  1916.     @@fini:
  1917.   mov    ax,si                ; success code in AX for return
  1918.   mov    [retval],ax
  1919.   pop    di si
  1920.   ret
  1921. ENDP
  1922.  
  1923.  
  1924. PROC    _chkbk    NEAR            ; bank switch check routine
  1925.   mov    di,0B800h
  1926.   mov    es,di
  1927.   xor    di,di
  1928.   mov    bx,1234h
  1929.   call    _gochk
  1930.   jnz    @@badchk
  1931.   mov    bx,4321h
  1932.   call    _gochk
  1933.   jnz    @@badchk
  1934.   clc
  1935.   ret
  1936.     @@badchk:
  1937.   stc
  1938.   ret
  1939. ENDP
  1940.  
  1941.  
  1942. PROC    _gochk    NEAR
  1943.   push    si
  1944.   mov    si,bx
  1945.  
  1946.   mov    al,cl
  1947.   call    dx
  1948.   xchg    bl,[es:di]
  1949.   mov    al,ch
  1950.   call    dx
  1951.   xchg    bh,[es:di]
  1952.  
  1953.   xchg    si,bx
  1954.  
  1955.   mov    al,cl
  1956.   call    dx
  1957.   xor    bl,[es:di]
  1958.   mov    al,ch
  1959.   call    dx
  1960.   xor    bh,[es:di]
  1961.  
  1962.   xchg    si,bx
  1963.  
  1964.   mov    al,ch
  1965.   call    dx
  1966.   mov    [es:di],bh
  1967.   mov    al,cl
  1968.   call    dx
  1969.   mov    [es:di],bl
  1970.  
  1971.   xor    al,al
  1972.   call    dx
  1973.   or    si,si
  1974.   pop    si
  1975.   ret
  1976. ENDP
  1977.  
  1978.  
  1979. PROC    _isport2    NEAR        ; check for valid I/O port
  1980.                     ; AL is index, AH is bit mask
  1981.   push    bx
  1982.   mov    bx,ax
  1983.   out    dx,al
  1984.   mov    ah,al
  1985.   inc    dx
  1986.   in    al,dx
  1987.   dec    dx
  1988.   xchg    al,ah
  1989.   push    ax
  1990.   mov    ax,bx
  1991.   out    dx,ax
  1992.   out    dx,al
  1993.   mov    ah,al
  1994.   inc    dx
  1995.   in    al,dx
  1996.   dec    dx
  1997.   and    al,bh
  1998.   cmp    al,bh
  1999.   jnz    @@noport
  2000.   mov    al,ah
  2001.   xor    ah,ah
  2002.   out    dx,ax
  2003.   out    dx,al
  2004.   mov    ah,al
  2005.   inc    dx
  2006.   in    al,dx
  2007.   dec    dx
  2008.   and    al,bh
  2009.   cmp    al,0
  2010.     @@noport:
  2011.   pop    ax
  2012.   out    dx,ax
  2013.   pop    bx
  2014.   ret
  2015. ENDP
  2016.  
  2017.  
  2018. PROC    _isport1    NEAR        ; check for valid I/O port
  2019.                     ; AL is bit mask
  2020.   mov    ah,al
  2021.   in    al,dx
  2022.   push    ax
  2023.   mov    al,ah
  2024.   out    dx,al
  2025.   in    al,dx
  2026.   and    al,ah
  2027.   cmp    al,ah
  2028.   jnz    @@noport
  2029.   xor    al,al
  2030.   out    dx,al
  2031.   in    al,dx
  2032.   and    al,ah
  2033.   cmp    al,0
  2034.     @@noport:
  2035.   pop    ax
  2036.   out    dx,al
  2037.   ret
  2038. ENDP
  2039.  
  2040.  
  2041. PROC    setMode    NEAR            ; Set 800x600x256
  2042.   mov    ax,SCREEN_WIDE
  2043.   mov    [scanline],ax
  2044.  
  2045.   cmp    [vesa],0
  2046.   jz    @@noVESA
  2047.   mov    bx,103h
  2048.   call    VESAset
  2049.   or    ax,ax                ; was function successful?
  2050. JUMPS
  2051.   jz    @@noSVGA            ; no, quit
  2052. NOJUMPS
  2053.   jmp    @@godo2
  2054.       @@noVESA:
  2055.   cmp    [genoa],0
  2056.   jz    @@noGenoa
  2057.   mov    ax,5Eh
  2058.   jmp    @@godo
  2059.     @@noGenoa:
  2060.   cmp    [ncr],0
  2061.   jz    @@noNCR
  2062.   mov    ax,5Ch
  2063.   jmp    @@godo
  2064.     @@noNCR:
  2065.   cmp    [oak067],0
  2066.   jz    @@noOak067
  2067.   mov    ax,54h
  2068.   jmp    @@godo
  2069.     @@noOak067:
  2070.   cmp    [aheada],0
  2071.   jnz    @@
  2072.   cmp    [aheadb],0
  2073.   jz    @@noAbove
  2074.     @@:
  2075.   mov    ax,62h
  2076.   jmp    short @@godo
  2077.     @@noAbove:
  2078.   cmp    [everex],0
  2079.   jz    @@noEverex
  2080.   mov    ax,70h
  2081.   mov    bl,31h
  2082.   jmp    short @@godo
  2083.     @@noEverex:
  2084.   cmp    [ativga],0
  2085.   jz    @@noATI
  2086.   mov    ax,63h
  2087.   jmp    short @@godo
  2088.     @@noATI:
  2089.   cmp    [trident],0
  2090.   jz    @@noTrident
  2091.   mov    ax,5Eh
  2092.   jmp    short @@godo
  2093.     @@noTrident:
  2094.   cmp    [video7],0
  2095.   jz    @@noVideo7
  2096.   mov    ax,6F05h
  2097.   mov    bl,69h
  2098.   jmp    short @@godo
  2099.     @@noVideo7:
  2100.   cmp    [chipstech],0
  2101.   jz    @@noChipsTech
  2102.   mov    ax,7Bh
  2103.   jmp    short @@godo
  2104.     @@noChipsTech:
  2105.   cmp    [paradise],0
  2106.   jz    @@noParadise
  2107.   mov    ax,5Ch
  2108.   jmp    short    @@godo
  2109.     @@noParadise:
  2110.   cmp    [tseng],0
  2111.   jz    @@noSVGA
  2112.   mov    ax,30h
  2113.  
  2114.     @@godo:
  2115.   int    10h
  2116.       @@godo2:
  2117.   mov    [curBank],-1
  2118.   mov    ax,1                ; return success code
  2119.   ret
  2120.  
  2121.     @@noSVGA:
  2122.   xor    ax,ax                ; return error code
  2123.   ret
  2124. ENDP
  2125.  
  2126.  
  2127. PROC    VESAset        NEAR
  2128.   push    di
  2129.  
  2130.   push    bx
  2131.   mov    ax,4F02h
  2132.   int    10h                   ; set the mode
  2133.   pop    cx
  2134.   or    ah,ah                ; was function successful?
  2135.   jz    @@noError                ; yes
  2136.   xor    ax,ax                ; set error code (for setMode)
  2137.   jmp    short    @@Exit
  2138.  
  2139.       @@noError:
  2140.   mov    ax,cs
  2141.   mov    es,ax
  2142.   mov    di,OFFSET modebuf
  2143.   mov    ax,4F01h
  2144.   int    10h                ; get the mode information
  2145.   mov    ax,[modebuf.WinSize]
  2146.   mov    [bksize],ax
  2147.   mov    ax,[modebuf.BytesPerLine]
  2148.   mov    [scanline],ax
  2149.   mov    ax,1                ; set success code (for setMode)
  2150.  
  2151.       @@Exit:
  2152.   pop    di
  2153.   ret
  2154. ENDP
  2155.  
  2156.  
  2157. PROC    makeAddrTable    NEAR
  2158.   LOCAL    temp:WORD
  2159.   push    si di
  2160.  
  2161.   mov    si,OFFSET lineOffs
  2162.   mov    di,OFFSET bankNum
  2163.   xor    bx,bx                ; current line number = 0
  2164.  
  2165.   mov    ax,[bksize]            ; separate process if bksize=64 K
  2166.   cmp    ax,64
  2167.   je    @@noBnk
  2168.  
  2169.   mov    cl,10
  2170.   shl    ax,cl                ; AX = bank size in bytes
  2171.   dec    ax
  2172.   mov    [temp],ax            ; [temp] = banksize in bytes - 1
  2173.   mov    cl,10
  2174.   mov    ax,[bksize]            ; AX = bank size in K
  2175.       @@shlp:
  2176.   inc    cl
  2177.   shr    ax,1
  2178.   jnz    @@shlp                ; loop until AX = 0
  2179.  
  2180.   xor    ax,ax                ; AX = 0
  2181.   xor    dx,dx                ; DX = 0
  2182.       @@lp:
  2183.   push    ax                ; store AX
  2184.   shr    ax,cl
  2185.   add    dx,ax                ; update current bank number
  2186.   pop    ax                ; restore AX
  2187.   and    ax,[temp]            ; mask offset so it's < bank size
  2188.   mov    [cs:si],ax            ; save line offset
  2189.   add    si,2                ; update pointer
  2190.   mov    [cs:di],dx            ; save bank number
  2191.   add    di,2                ; update pointer
  2192.   add    ax,[scanline]            ; update offset
  2193.   inc    bx                ; update line number
  2194.   cmp    bx,SCREEN_DEEP
  2195.   jb    @@lp                ; loop until all lines done
  2196.   jmp    short    @@calcBankChange    ; calculate bank change table
  2197.  
  2198.       @@noBnk:
  2199.   xor    ax,ax                ; AX = 0
  2200.   xor    dx,dx                ; DX = 0
  2201.   mov    cx,[scanline]            ; CX = width of line in bytes
  2202.       @@nlp:
  2203.   mov    [cs:si],ax            ; store line offset
  2204.   add    si,2                ; update pointer
  2205.   mov    [cs:di],dx            ; store bank number
  2206.   add    di,2                ; update pointer
  2207.   add    ax,cx                ; add another line width
  2208.   adc    dx,0                ; increase bank number if overflow
  2209.   inc    bx                ; update current line number
  2210.   cmp    bx,SCREEN_DEEP
  2211.   jb    @@nlp                ; jump until all lines done
  2212.  
  2213.       @@calcBankChange:
  2214.   mov    di,OFFSET bankChanges        ; initialize pointer
  2215.   xor    ax,ax                ; AX = current line
  2216.       @@bankChangeLoop:
  2217.   mov    bx,ax                ; BX = current line
  2218.   shl    bx,1                ; to access a table of words
  2219.   mov    dx,[cs:bankNum+bx]        ; DX = bank at start of current line
  2220.   mov    bx,ax                ; BX = current line
  2221.   inc    bx                ; BX = next line
  2222.   shl    bx,1                ; to access a table of words
  2223.   mov    cx,[cs:bankNum+bx]        ; CX = bank at start of next line
  2224.   mov    si,[cs:lineOffs+bx]        ; SI = offset at start of next line
  2225.   or    si,si                ; is SI=0?
  2226.   jz    @@L1                ; yes, jump
  2227.   dec    cx                ; CX = bank at end of current line
  2228.       @@L1:
  2229.   cmp    cx,dx                ; are start and end banks the same?
  2230.   jne    @@newBank            ; bank changed, jump
  2231.   mov    [word ptr cs:di],1        ; store bank changed flag
  2232.   jmp    short    @@L2            ; jump
  2233.       @@newBank:
  2234.   mov    [word ptr cs:di],0        ; store bank same flag
  2235.       @@L2:
  2236.   add    di,2                ; update pointer
  2237.   inc    ax                ; update current line number
  2238.   cmp    ax,SCREEN_DEEP
  2239.   jb    @@bankChangeLoop        ; loop until all lines done
  2240.  
  2241.   pop    di si
  2242.   ret
  2243. ENDP
  2244.  
  2245.  
  2246.     ENDS
  2247.  
  2248. END